﻿using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web.Mvc;
using CultuRAM.Models;
using CultuRAM.DAL;
using PagedList;

namespace CultuRAM.Controllers
{
    [Authorize]
    public class ResourceController : Controller
    {
        private readonly UnitOfWork _unitOfWork = EventController._unitOfWork;
        private readonly CacheMode _cacheMode = EventController._CacheMode;

        //
        // GET: /Resource/Default

        public ActionResult Default()
        {
            return PartialView("_Default");
        }

        // 
        // GET: /Resource/

        public ActionResult IndexPv(int page, int idEvent)
        {
            var lista = GetResourcesByEventIdPaged(idEvent, _cacheMode.Active, page);
            
            ViewBag.idEv = idEvent;

            return PartialView("_Index", lista);
        }

        // 
        // GET: /Resource/Create

        public PartialViewResult CreatePv(int idEvent = 0)
        {
            var cm = _cacheMode;

            Resource lastOrDefault;

            if (!_cacheMode.Active)
            {
                lastOrDefault = _unitOfWork.ResourceRepository.Get().LastOrDefault();
            }
            else
            {
                lastOrDefault = _cacheMode.ResourcesList.Any() ?
                    _cacheMode.ResourcesList.ToList().LastOrDefault() :
                    _unitOfWork.ResourceRepository.Get().LastOrDefault();
            }

            var lastIdRes = lastOrDefault != null ? lastOrDefault.ResId + 1 : 1;

            var res = new Resource()
            {
                ResId = lastIdRes,
                EventId = idEvent,
            };

            var ms = ModelState.IsValid;

            ViewBag.ResourceTypes = PopulateResourceTypeDropDownList();

            return PartialView("Create", res);
        }

        // 
        // POST: /Resource/Create

        [HttpPost]
        public PartialViewResult CreatePv(Resource resource)
        {
            var evTemp = _cacheMode.EventsList.ToList().FirstOrDefault(ev => ev.EventId == resource.EventId);

            resource.Event = evTemp;
            resource.ResourceType = _unitOfWork.ResourceTypeRepository.GetByID(resource.ResTypeId);

            if (ModelState.IsValid)
            {
                try
                {
                    if (_cacheMode.Active)
                    {
                        _cacheMode.ResourcesList.Add(resource);
                    }
                    else
                    {
                        var evTempUw = _unitOfWork.EventRepository.GetByID(resource.EventId);
                        resource.Event = evTempUw;

                        _unitOfWork.ResourceRepository.Insert(resource);
                        _unitOfWork.Save();
                    }

                    ViewBag.MsgSuccess = "O Recurso foi registado com Sucesso!";
                    return PartialView("_Default");

                }

                catch (DataException ex)
                {
                    var error = ex;
                }
            }

            ViewBag.ResourceTypes = PopulateResourceTypeDropDownList(resource.ResTypeId);

            return PartialView("Create", resource);
        }


        // 
        // GET: /Resource/Edit/5

        public PartialViewResult EditPv(int id = 0)
        {
            if (id == 0)
            {
                ViewBag.MsgWarning = new MvcHtmlString("<b>ATENÇÃO:</b><br> Selecione o recurso que pretende editar, clicando numa das linhas da tabela!");
                return PartialView("_Default");
            }

            Resource resource = null;

            if (_cacheMode.Active)
            {
                foreach (var item in _cacheMode.ResourcesList.Where(item => item.ResId == id))
                {
                    resource = item;
                    break;
                }
            }
            else
            {
                resource = _unitOfWork.ResourceRepository.GetByID(id);
            }


            if (resource == null)
            {
                ViewBag.MsgError = "Ocorreu um erro ao tentar editar o Recurso. Certifique-se que selecionou um recurso!";
                return PartialView("_Default");
            }


            var evId = resource.EventId == 0 ? resource.Event.EventId : resource.EventId;

            ViewBag.ResourceTypes = PopulateResourceTypeDropDownList(resource.ResId);
            //ViewBag.Events = PopulateEventDropDownList(resource.EventId);

            return PartialView("Edit", resource);
        }

        // 
        // POST: /Resource/Edit/5

        [HttpPost]
        public PartialViewResult EditPv(Resource resource)
        {
            var evId = resource.EventId == 0 ? resource.Event.EventId : resource.EventId;

            resource.ResTypeId = resource.ResTypeId;

            var ev = new Event();
            var listRes = new List<Resource>();

            if (_cacheMode.Active)
            {
                foreach (var item in _cacheMode.EventsList.Where(item => item.EventId == evId))
                {
                    resource.Event = item;
                    ev = item;
                }

                listRes.AddRange(_cacheMode.ResourcesList.Where(item => item.EventId == evId));
                ev.Resources = listRes.ToList();
            }
            else
            {
                foreach (var item in _unitOfWork.EventRepository.Get().Where(item => item.EventId == evId))
                {
                    resource.Event = item;
                    ev = item;
                }

                ev.Resources = GetResourcesByEventId(evId, _cacheMode.Active);
            }


            resource.EventId = evId;
            resource.ResourceType = _unitOfWork.ResourceTypeRepository.GetByID(resource.ResTypeId);

            if (ModelState.IsValid)
            {
                if (_cacheMode.Active)
                {
                    //Alterar o recurso na Lista de Recursos
                    foreach (var item in _cacheMode.ResourcesList.Where(item => item.ResId == resource.ResId))
                    {
                        _cacheMode.ResourcesList.Remove(item);
                        _cacheMode.ResourcesList.Add(resource);
                        break;
                    }

                    //Alterar o recurso no Evento
                    foreach (var item in ev.Resources.Where(item => item.ResId == resource.ResId))
                    {
                        ev.Resources.Remove(item);
                        ev.Resources.Add(resource);
                        break;
                    }
                }

                else
                {
                    _unitOfWork.ResourceRepository.Update(resource);
                    //_unitOfWork.EventRepository.Update(ev);
                    _unitOfWork.Save();
                }

                ViewBag.MsgSuccess = "O Recurso foi alterado com sucesso!";
                return PartialView("_Default");
            }

            ViewBag.ResourceTypes = PopulateResourceTypeDropDownList(resource.ResId); 

            return PartialView("Edit", resource);
        }


        // 
        // GET: /Resource/Delete/5

        public PartialViewResult DeletePv(int id = 0)
        {
            if (id == 0)
            {
                ViewBag.MsgWarning = new MvcHtmlString("<b>ATENÇÃO:</b><br> Selecione o recurso que pretende editar, clicando numa das linhas da tabela!");
                return PartialView("_Default");
            }

            Resource resource = null;

            if (_cacheMode.Active)
            {
                foreach (var item in _cacheMode.ResourcesList.Where(item => item.ResId == id))
                {
                    resource = item;
                    break;
                }
            }
            else
            {
                resource = _unitOfWork.ResourceRepository.GetByID(id);
            }

            if (resource == null)
            {
                ViewBag.MsgError = "Ocorreu um erro ao tentar eliminar o Recurso. Certifique-se que selecionou um recurso!";
                return PartialView("_Default");
            }

            var evId = resource.EventId == 0 ? resource.Event.EventId : resource.EventId;

            ViewBag.Places = PopulateResourceTypeDropDownList(resource.ResTypeId);
            ViewBag.Events = PopulateEventDropDownList(resource.EventId);

            return PartialView("Delete", resource);
        }

        // 
        // POST: /Resource/Delete/5

        [HttpPost, ActionName("DeletePv")]
        public PartialViewResult DeleteConfirmedPv(Resource resource)
        {
            var evId = resource.EventId == 0 ? resource.Event.EventId : resource.EventId;

            if (_cacheMode.Active)
            {

                foreach (var item in _cacheMode.EventsList.Where(item => item.EventId == evId))
                {
                    resource.Event = item;
                }
            }

            resource.EventId = evId;

            if (ModelState.IsValid)
            {
                if (_cacheMode.Active)
                {
                    foreach (var item in _cacheMode.ResourcesList.Where(item => item.ResId == resource.ResId))
                    {
                        _cacheMode.ResourcesList.Remove(item);
                        break;
                    }
                }
                else
                {
                    _unitOfWork.ResourceRepository.Delete(resource.ResId);
                    _unitOfWork.Save();
                }

                ViewBag.MsgSuccess = "O Recurso foi eliminado com sucesso!";
                return PartialView("_Default");
            }


            ViewBag.Places = PopulateResourceTypeDropDownList(resource.ResTypeId);
            ViewBag.Events = PopulateEventDropDownList(resource.EventId);

            return PartialView("Delete", resource);
        }



        //AUXILIARY METHODS /////////////////////////////////////////////////////////

        #region Auxiliary_Methods

        //Method: Get the list of all Resources by ID - Paged
        public IPagedList<Resource> GetResourcesByEventIdPaged(int eventId, bool activeCache, int page = 1)
        {
            return activeCache ? _cacheMode.ResourcesList.Where(x => x.EventId == eventId).ToPagedList(page, 7)
                : _unitOfWork.ResourceRepository.Get(filter: x => x.EventId == eventId).OrderByDescending(o => o.ResId).ToPagedList(page, 7);
        }

        //Method: Get the list of all Resources by ID
        public IList<Resource> GetResourcesByEventId(int eventId, bool activeCache, int page = 1)
        {
            return activeCache ? _cacheMode.ResourcesList.Where(x => x.EventId == eventId).ToList()
                : _unitOfWork.ResourceRepository.Get(filter: x => x.EventId == eventId).OrderByDescending(o => o.ResId).ToList();
        }

        //Method: Populate the DropDownList of ResourceType
        private SelectList PopulateResourceTypeDropDownList(int? selectedResTypeId = 0)
        {
            var resTypes = _unitOfWork.ResourceTypeRepository.GetList().OrderBy(o => o.ResType);
            return selectedResTypeId != 0 ?
                new SelectList(resTypes, "ResTypeId", "ResType") :
                new SelectList(resTypes, "ResTypeId", "ResType", selectedResTypeId);
        }

        //Method: Populate the DropDownList of Event
        private SelectList PopulateEventDropDownList(int? selectedEventId = 0)
        {
            var events = _unitOfWork.EventRepository.GetList();

            return selectedEventId == 0 ?
                 new SelectList(events, "EventId", "Title") :
                 new SelectList(events, "EventId", "Title", selectedEventId);
        }

        #endregion

    }//Class ResourceController

} //Namespace CultuRAM.Controllers

